using System;
using System.Linq;
using System.Diagnostics.Contracts;
using System.Collections.Generic;

namespace ReactiveCode.Statements
{
    internal class RootStatement : MethodCall, IReactive
    {
        public new ReactiveHost Host { get; private set; }
        LinkedListNode<RootStatement> _node;

        public Time ActivationTime { get; private set; }

        public RootStatement(ReactiveHost host, ReactiveMethod method)
            : base(method)
        {
            Contract.Requires(host != null);
            Host = host;
            Root = this;
            EnabledProperty.Where(x => x).Subscribe(_ => ActivationTime = Time.Current);
            _node = host._calls.AddLast(this);
        }

        bool IReactive.Enabled
        {
            get { return Enabled; }
            set { Enabled = value; }
        }

        public override void Dispose()
        {
            _node.List.Remove(_node);
            base.Dispose();
        }
    }
    class RootStatement<T> : RootStatement, IReactive<T>
    {
        public RootStatement(ReactiveHost host, ReactiveMethod<T> method)
            : base(host, method)
        {

        }

        public IObservable<T> Value
        {
            get
            {
                var method = (ReactiveMethod<T>)Method;
                return method.ReturnValue;
            }
        }
    }
}